#include "common/agecalc/agecalc.h"
#include <QDateTime>
#include <QString>

QString AgeCalc::getAgeByCodeInDH(const QString& code)
{
	if (code.isEmpty())
	{
		return {};
	}

	QString ret = "";
	qint32 year = code.midRef(0, 3).toInt();
	qint32 month = code.midRef(3, 2).toInt();
	qint32 day = code.midRef(5, 2).toInt();

	if (year >= 1)
	{
		ret += QString::number(year) + "岁";
		if (year >= 14) return ret;
		if (month >= 1) ret += QString::number(month) + "月";
		return ret.isEmpty() ? "1天" : ret;
	}

	if (month >= 1)
	{
		ret += QString::number(month) + "月";
		if (day >= 1) ret += QString::number(day) + "天";
		return ret;
	}

	return (day >= 1) ? QString::number(day) + "天" : "1天";
}

QString AgeCalc::getAgeByCode(const QString& code, bool showMinute)
{
	if (code.isEmpty())
	{
		return {};
	}

	qint32 year = code.midRef(0, 3).toInt();
	qint32 month = code.midRef(3, 2).toInt();
	qint32 day = code.midRef(5, 2).toInt();
	qint32 hour = code.midRef(7, 2).toInt();
	qint32 minute = code.midRef(9, 2).toInt();

	if (year != 0)
	{
		return QString::number(year) + "岁";
	}
	if (month != 0)
	{
		return QString::number(month) + "月";
	}
	if (day != 0)
	{
		return QString::number(day) + "天";
	}
	if (hour != 0)
	{
		return QString::number(hour) + "小时";
	}
	if (showMinute)
	{
		if (minute != 0)
		{
			return QString::number(minute) + "分钟";
		}
	}
	return {};
}


QString AgeCalc::getAgeCode(const QDateTime& birthDay, const QDateTime& calcDay, bool showMinute)
{
	if (calcDay < birthDay)
	{
		return {};
	}
	qint32 year = calcDay.date().year() - birthDay.date().year();
	qint32 month = calcDay.date().month() - birthDay.date().month();
	qint32 day = calcDay.date().day() - birthDay.date().day();
	qint32 hour = calcDay.time().hour() - birthDay.time().hour();
	qint32 minute = calcDay.time().minute() - birthDay.time().minute();

	if (minute < 0)
	{
		minute += 60;
		--hour;
	}
	if (hour < 0)
	{
		hour += 24;
		--day;
	}
	// 处理不同月份的天数
	if (day < 0)
	{
		day += calcDay.date().addMonths(-1).daysInMonth();
		--month;
	}
	if (month < 0)
	{
		month += 12;
		--year;
	}
	QString ret;
	ret += year > 0 ? QString::number(year).rightJustified(3, '0') : "000";
	ret += month > 0 ? QString::number(month).rightJustified(2, '0') : "00";
	ret += day > 0 ? QString::number(day).rightJustified(2, '0') : "00";
	ret += hour > 0 ? QString::number(hour).rightJustified(2, '0') : "00";
	if (showMinute)
	{
		ret += minute > 0 ? QString::number(minute).rightJustified(2, '0') : "00";
	}
	return ret;
}


// std::nullopt
QDateTime AgeCalc::calcBirthDay(const QDateTime& date, std::optional<int> year, std::optional<int> month, std::optional<int> day, std::optional<int> hour, std::optional<int> minute)
{
	QDateTime newTime = date;
	if (year.has_value())
	{
		newTime = newTime.addYears(-*year);
	}
	if (month.has_value())
	{
		newTime = newTime.addMonths(-*month);
	}
	if (day.has_value())
	{
		newTime = newTime.addDays(-*day);
	}
	if (hour.has_value())
	{
		newTime = newTime.addSecs(-*hour * 3600);
	}
	if (minute.has_value())
	{
		newTime = newTime.addSecs(-*minute * 60);
	}
	return newTime;
}

QDateTime AgeCalc::calcBirthDay(const QDateTime& date, std::optional<int> year, std::optional<int> month, std::optional<int> day, std::optional<int> hour)
{
	return calcBirthDay(date, year, month, day, hour, std::nullopt);
}
QDateTime AgeCalc::calcBirthDay(const QDateTime& date, std::optional<int> year, std::optional<int> month, std::optional<int> day)
{
	return calcBirthDay(date, year, month, day, std::nullopt);
}
QDateTime AgeCalc::calcBirthDay(const QDateTime& date, std::optional<int> year, std::optional<int> month)
{
	return calcBirthDay(date, year, month, std::nullopt);
}
QDateTime AgeCalc::calcBirthDay(const QDateTime& date, std::optional<int> year)
{
	return calcBirthDay(date, year, std::nullopt);
}

QString AgeCalc::getAgeString(std::optional<QDateTime> birthDay, std::optional<QDateTime> calcDay)
{
	if (!birthDay.has_value() || !calcDay.has_value())
	{
		return {};
	}
	if (*calcDay < *birthDay)
	{
		return "0岁";
	}

	qint32 year = calcDay->date().year() - birthDay->date().year();
	qint32 month = calcDay->date().month() - birthDay->date().month();
	qint32 day = calcDay->date().day() - birthDay->date().day();
	qint32 hour = calcDay->time().hour() - birthDay->time().hour();
	qint32 minute = calcDay->time().minute() - birthDay->time().minute();

	if (minute < 0)
	{
		minute += 60;
		--hour;
	}
	if (hour < 0)
	{
		hour += 24;
		--day;
	}
	// 处理不同月份的天数
	if (day < 0)
	{
		day += calcDay->date().addMonths(-1).daysInMonth();
		--month;
	}
	if (month < 0)
	{
		month += 12;
		--year;
	}

	QString result;
	if (year > 0)
	{
		return QString("%1岁").arg(year);
	}
	if (month > 0)
	{
		return QString("%1月").arg(month);
	}
	if (day > 0)
	{
		return QString("%1天").arg(day);
	}
	if (hour > 0)
	{
		return QString("%1时").arg(hour);
	}
	if (minute > 0)
	{
		return QString("%1分").arg(minute);
	}

	return "0岁";
}


QString AgeCalc::getAge(std::optional<QDateTime> birthDay, std::optional<QDateTime> calcDay, const QString& formatStr, bool isEmr, const QString& zeroUnit)
{
	if (formatStr.isEmpty())
	{
		return getAgeString(birthDay, calcDay);
	}

	QString result = getAgeString(birthDay, calcDay);
	if (isEmr && !zeroUnit.isEmpty() && result == QString("0岁"))
	{
		return QString("0" + zeroUnit);
	}
	qint32 a = calcDay->date().year();
	qint32 b = birthDay->date().year();
	qint32 year = a - b;
	qint32 month = calcDay->date().month() - birthDay->date().month();
	qint32 day = calcDay->date().day() - birthDay->date().day();
	qint32 hour = calcDay->time().hour() - birthDay->time().hour();
	qint32 minute = calcDay->time().minute() - birthDay->time().minute();
	if (minute < 0)
	{
		minute += 60;
		--hour;
	}
	if (hour < 0)
	{
		hour += 24;
		--day;
	}
	// 处理不同月份的天数
	if (day < 0)
	{
		day += calcDay->date().addMonths(-1).daysInMonth();
		--month;
	}
	if (month < 0)
	{
		month += 12;
		--year;
	}

	QStringList formats = formatStr.split('|');
	int type = 1;
	int gt = 14;
	int lt = 14;
	QString ret;
	for (const auto& formatString: formats)
	{
		int l = formatString.indexOf('(');
		int r = formatString.indexOf(')', l);

		type = formatString.left(l).toInt();
		QStringList parts = formatString.mid(l + 1, r - l - 1).split(',');

		gt = parts.value(0).toInt();
		lt = parts.value(1, "0").toInt();

		switch (static_cast<AgeCalcType>(type))
		{
		case AgeCalcType::Y:
			if (year >= gt)
			{
				ret = QString("%1岁").arg(year);
				return ret; // 命中直接返回
			}
			break;
		case AgeCalcType::YM:
			if (gt > year && year >= lt)
			{
				ret = month == 0 ? QString("%1岁").arg(year)
								 : QString("%1岁%2月").arg(year).arg(month);
				return ret;
			}
			break;
		case AgeCalcType::M:
			if (gt > month && month >= lt)
			{
				ret = QString("%1月").arg(month);
				return ret;
			}
			break;
		case AgeCalcType::MD:
			if (gt > month && month >= lt)
			{
				ret = day == 0 ? QString("%1月").arg(month)
							   : QString("%1月%2天").arg(month).arg(day);
				return ret;
			}
			break;
		case AgeCalcType::D:
			if (gt > day && day >= lt)
			{
				ret = QString("%1天").arg(day);
				return ret;
			}
			break;
		case AgeCalcType::DH:
			if (gt >= day && day >= lt)
			{
				ret = hour == 0 ? QString("%1天").arg(day)
								: QString("%1天%2小时").arg(day).arg(hour);
				return ret;
			}
			break;
		case AgeCalcType::H:
			if (gt > hour && hour >= lt)
			{
				ret = QString("%1小时").arg(hour);
				return ret;
			}
			break;
		case AgeCalcType::HMI:
			if (gt >= hour && hour >= lt)
			{
				ret = minute == 0 ? QString("%1小时").arg(hour)
								  : QString("%1小时%2分钟").arg(hour).arg(minute);
				if (hour == 0)
				{
					ret = QString("%1分钟").arg(minute);
				}
				return ret;
			}
			break;
		}
	}
	return QString();
}
QString AgeCalc::getNewBabyAgeString(std::optional<QDateTime> birthDay, std::optional<QDateTime> calcDay)
{
	if (!birthDay.has_value() || !calcDay.has_value())
	{
		return {};
	}

	// 如果目标日期比生日早，直接返回空
	if (*calcDay < *birthDay)
	{
		return {};
	}

	// 计算 totalMonths
	int totalMonths = calcDay->date().year() * 12 + calcDay->date().month() - (birthDay->date().year() * 12 + birthDay->date().month());

	if (calcDay->date().day() < birthDay->date().day())
	{
		totalMonths--;
	}

	int totalYears = totalMonths / 12;

	QDate tmp = birthDay->date().addMonths(totalMonths);
	int days = tmp.daysTo(calcDay->date());

	QString ret;
	if (totalYears == 0 && totalMonths != 0 && days != 0)
	{
		ret = QString("%1 %2/30").arg(totalMonths).arg(days);
	}
	else if (totalYears == 0 && totalMonths != 0 && days == 0)
	{
		ret = QString("%1").arg(totalMonths);
	}
	else if (totalYears == 0 && totalMonths == 0)
	{
		ret = QString("%1/30").arg(days);
	}
	return ret;
}

